package com.google.android.apps.wakemewhere.ui;

import java.util.List;
import java.util.logging.Logger;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.apps.wakemewhere.IntentExtras;
import com.google.android.apps.wakemewhere.R;
import com.google.android.apps.wakemewhere.mapsearch.SearchResult;
import com.google.android.apps.wakemewhere.mapsearch.SearchResultAggregator;
import com.google.android.apps.wakemewhere.mapsearch.SearchResultCallback;
import com.google.android.apps.wakemewhere.mapsearch.SearchResultProvider;
import com.google.android.apps.wakemewhere.mapsearch.SearchTimeout;
import com.google.android.apps.wakemewhere.util.Preconditions;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

/**
 * @author baran@google.com (Baran Ozgul)
 */
public class LocationPickerActivity extends MapActivity implements SearchResultCallback {

	private static final Logger logger = Logger.getLogger(LocationPickerActivity.class.getName());
	
	private Button doneButton;
	private Button cancelButton;
	private MapView mapView;
	private EditText searchEditText;
	
	private MapToastOverlay overlay;
	
	private long alarmId = -1L;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mapview);
		
		alarmId = getIntent().getLongExtra(IntentExtras.ALARM_ID, -1L);
				
		mapView = (MapView) findViewById(R.id.mapView);
		
		doneButton = (Button) findViewById(R.id.save_location);
		doneButton.setOnClickListener(new DoneListener());
		
		cancelButton = (Button) findViewById(R.id.cancel_location);
		cancelButton.setOnClickListener(new CancelListener());
		
		searchEditText = (EditText) findViewById(R.id.search_edit_box);
		searchEditText.setOnKeyListener(new SearchEditTextKeyListener());
		
		overlay = new MapToastOverlay(getBaseContext());
		
		mapView.setBuiltInZoomControls(true);
		mapView.getOverlays().add(overlay);
		mapView.invalidate();		      
	}


	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
		
	private void doSearch() {
		if (mapView == null || searchEditText == null || searchEditText.getText().length() == 0) {
			return;
		}
		
		ProgressDialog dialog = ProgressDialog.show(LocationPickerActivity.this, "", getString(R.string.searching, true));
		String query = searchEditText.getText().toString();
		GeoPoint mapLowerLeft = mapView.getProjection().fromPixels(0, mapView.getHeight());
		GeoPoint mapUpperRight = mapView.getProjection().fromPixels(mapView.getWidth(), 0);
		Logger.getLogger("LPA_SEARCH").warning("map lower left =  " + mapLowerLeft);
		Logger.getLogger("LPA_SEARCH").warning("map upper right = " + mapUpperRight);
		
		SearchTimeout timeout = new SearchTimeout(this, dialog);
		SearchResultAggregator search = new SearchResultAggregator(getApplicationContext(), timeout);
		search.asyncSearch(query, search, dialog, mapLowerLeft, mapUpperRight);
	}
	
	public void onSearchResults(List<SearchResult> results, Object tag, SearchResultProvider provider, boolean finished) {
		if (tag instanceof Dialog) {
			hide((Dialog) tag);
		}
		
		if (finished && results.isEmpty()) {
			noResults();
		} else if (!results.isEmpty()) {
			updateResults(results);
		}
	}
	
	private void hide(final Dialog dialog) {
		runOnUiThread(new Runnable() { public void run() {
			if (dialog.isShowing()) {
				dialog.hide();
			}
		}});
	}
	
	private Parcelable[] asParcelableArray(List<SearchResult> results) {
		Parcelable[] out = new Parcelable[results.size()];
		results.toArray(out);
		return out;
	}

	private void noResults() {
		runOnUiThread(new Runnable() { public void run() {
			Toast.makeText(getApplicationContext(), R.string.no_search_results, Toast.LENGTH_LONG).show();
		}});
	}
	
	private void updateResults(List<SearchResult> results) {
		logger.warning("FIRE!!!! RESULTS RECIEVED!");
		for (SearchResult result : results) {
			logger.warning("THIS IS A RESULT: " + result);
		}
		Intent resultsIntent = new Intent(getApplicationContext(), SearchResultsActivity.class);
		resultsIntent.putExtra(IntentExtras.RESULTS, asParcelableArray(results));
		resultsIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
		startActivityForResult(resultsIntent, 0);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (data != null && data.hasExtra(IntentExtras.ADDRESS) && 
				            data.hasExtra(IntentExtras.LATITUDE) && 
				            data.hasExtra(IntentExtras.LONGITUDE)) {
			String pickedAddress = data.getStringExtra(IntentExtras.ADDRESS);
			int latitudeE6 = data.getIntExtra(IntentExtras.LATITUDE, 0);
			int longitudeE6 = data.getIntExtra(IntentExtras.LONGITUDE, 0);
			//searchEditText.setText(latitudeE6/10e6d + ", " + longitudeE6/10e6d);
			GeoPoint location = new GeoPoint(latitudeE6, longitudeE6);
			logger.info("Address picked: " + pickedAddress + " " + location);
			mapView.getController().animateTo(location);
			mapView.getController().zoomToSpan((int)(0.005 * 10e6), (int)(0.005 * 10e6));
			overlay.setAlarmArea(location, mapView, 60);
		} else {
			logger.info("No result picked");
		}
	}
		
	private class SearchEditTextKeyListener implements OnKeyListener {

		public boolean onKey(View v, int keyCode, KeyEvent event) {
			if (keyCode == KeyEvent.KEYCODE_ENTER) {
				doSearch();
				return true;
			}
			return false;
		}
	}

	private Intent createIntentWithLocation(View view) {
		GeoPoint point = overlay.getGeoPoint();
		Preconditions.nonNull(point);
		Intent intent = new Intent(view.getContext(), SetAlarmActivity.class);
		intent.putExtra(IntentExtras.ALARM_ID, alarmId); 
		long latitudeE6 = point.getLatitudeE6();
		long longitudeE6 = point.getLongitudeE6();
		intent.putExtra(IntentExtras.LATITUDE, latitudeE6);
		intent.putExtra(IntentExtras.LONGITUDE, longitudeE6);
		return intent;
	}
	
	private void done(View view) {
		Preconditions.nonNull(overlay.getGeoPoint());
		Intent intentWithLocation = createIntentWithLocation(view);
		if (getCallingActivity() != null) {
			setResult(RESULT_OK, intentWithLocation);
			finish();
		} else {
			view.getContext().startActivity(intentWithLocation);
		}
	}
	
	private class DoneListener implements OnClickListener {
		public void onClick(View view) {
			done(view);
		}
	}
	
	private class CancelListener implements OnClickListener {
		public void onClick(View view) {
			setResult(RESULT_CANCELED);
			LocationPickerActivity.this.finish();
		}
	}
}
